home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / machine / 6821pia.c next >
C/C++ Source or Header  |  2000-04-23  |  23KB  |  801 lines

  1. /**********************************************************************
  2.  
  3.     Motorola 6821 PIA interface and emulation
  4.  
  5.     This function emulates all the functionality of up to 8 M6821
  6.     peripheral interface adapters.
  7.  
  8. **********************************************************************/
  9.  
  10. #include <string.h>
  11. #include <stdio.h>
  12. #include "driver.h"
  13. #include "6821pia.h"
  14.  
  15.  
  16. #define VERBOSE 0
  17.  
  18. #if VERBOSE
  19. #define LOG(x)    logerror x
  20. #else
  21. #define LOG(x)
  22. #endif
  23.  
  24.  
  25. /******************* internal PIA data structure *******************/
  26.  
  27. struct pia6821
  28. {
  29.     const struct pia6821_interface *intf;
  30.     UINT8 addr;
  31.  
  32.     UINT8 in_a;
  33.     UINT8 in_ca1;
  34.     UINT8 in_ca2;
  35.     UINT8 out_a;
  36.     UINT8 out_ca2;
  37.     UINT8 ddr_a;
  38.     UINT8 ctl_a;
  39.     UINT8 irq_a1;
  40.     UINT8 irq_a2;
  41.     UINT8 irq_a_state;
  42.  
  43.     UINT8 in_b;
  44.     UINT8 in_cb1;
  45.     UINT8 in_cb2;
  46.     UINT8 out_b;
  47.     UINT8 out_cb2;
  48.     UINT8 ddr_b;
  49.     UINT8 ctl_b;
  50.     UINT8 irq_b1;
  51.     UINT8 irq_b2;
  52.     UINT8 irq_b_state;
  53. };
  54.  
  55.  
  56. /******************* convenince macros and defines *******************/
  57.  
  58. #define PIA_IRQ1                0x80
  59. #define PIA_IRQ2                0x40
  60.  
  61. #define IRQ1_ENABLED(c)            (c & 0x01)
  62. #define IRQ1_DISABLED(c)        (!(c & 0x01))
  63. #define C1_LOW_TO_HIGH(c)        (c & 0x02)
  64. #define C1_HIGH_TO_LOW(c)        (!(c & 0x02))
  65. #define OUTPUT_SELECTED(c)        (c & 0x04)
  66. #define DDR_SELECTED(c)            (!(c & 0x04))
  67. #define IRQ2_ENABLED(c)            (c & 0x08)
  68. #define IRQ2_DISABLED(c)        (!(c & 0x08))
  69. #define STROBE_E_RESET(c)        (c & 0x08)
  70. #define STROBE_C1_RESET(c)        (!(c & 0x08))
  71. #define SET_C2(c)                (c & 0x08)
  72. #define RESET_C2(c)                (!(c & 0x08))
  73. #define C2_LOW_TO_HIGH(c)        (c & 0x10)
  74. #define C2_HIGH_TO_LOW(c)        (!(c & 0x10))
  75. #define C2_SET_MODE(c)            (c & 0x10)
  76. #define C2_STROBE_MODE(c)        (!(c & 0x10))
  77. #define C2_OUTPUT(c)            (c & 0x20)
  78. #define C2_INPUT(c)                (!(c & 0x20))
  79.  
  80.  
  81.  
  82.  
  83. /******************* static variables *******************/
  84.  
  85. static struct pia6821 pia[MAX_PIA];
  86.  
  87. static const UINT8 swizzle_address[4] = { 0, 2, 1, 3 };
  88.  
  89.  
  90.  
  91. /******************* un-configuration *******************/
  92.  
  93. void pia_unconfig(void)
  94. {
  95.     memset(&pia, 0, sizeof(pia));
  96. }
  97.  
  98.  
  99. /******************* configuration *******************/
  100.  
  101. void pia_config(int which, int addressing, const struct pia6821_interface *intf)
  102. {
  103.     if (which >= MAX_PIA) return;
  104.     pia[which].intf = intf;
  105.     pia[which].addr = addressing;
  106. }
  107.  
  108.  
  109. /******************* reset *******************/
  110.  
  111. void pia_reset(void)
  112. {
  113.     int i;
  114.  
  115.     /* zap each structure, preserving the interface and swizzle */
  116.     for (i = 0; i < MAX_PIA; i++)
  117.     {
  118.         const struct pia6821_interface *intf = pia[i].intf;
  119.         UINT8 addr = pia[i].addr;
  120.  
  121.         memset(&pia[i], 0, sizeof(pia[i]));
  122.  
  123.         pia[i].intf = intf;
  124.         pia[i].addr = addr;
  125.     }
  126. }
  127.  
  128.  
  129. /******************* wire-OR for all interrupt handlers *******************/
  130.  
  131. static void update_shared_irq_handler(void (*irq_func)(int state))
  132. {
  133.     int i;
  134.  
  135.     /* search all PIAs for this same IRQ function */
  136.     for (i = 0; i < MAX_PIA; i++)
  137.         if (pia[i].intf)
  138.         {
  139.             /* check IRQ A */
  140.             if (pia[i].intf->irq_a_func == irq_func && pia[i].irq_a_state)
  141.             {
  142.                 (*irq_func)(1);
  143.                 return;
  144.             }
  145.  
  146.             /* check IRQ B */
  147.             if (pia[i].intf->irq_b_func == irq_func && pia[i].irq_b_state)
  148.             {
  149.                 (*irq_func)(1);
  150.                 return;
  151.             }
  152.         }
  153.  
  154.     /* if we found nothing, the state is off */
  155.     (*irq_func)(0);
  156. }
  157.  
  158.  
  159. /******************* external interrupt check *******************/
  160.  
  161. static void update_6821_interrupts(struct pia6821 *p)
  162. {
  163.     int new_state;
  164.  
  165.     /* start with IRQ A */
  166.     new_state = 0;
  167.     if ((p->irq_a1 && IRQ1_ENABLED(p->ctl_a)) || (p->irq_a2 && IRQ2_ENABLED(p->ctl_a))) new_state = 1;
  168.     if (new_state != p->irq_a_state)
  169.     {
  170.         p->irq_a_state = new_state;
  171.         if (p->intf->irq_a_func) update_shared_irq_handler(p->intf->irq_a_func);
  172.     }
  173.  
  174.     /* then do IRQ B */
  175.     new_state = 0;
  176.     if ((p->irq_b1 && IRQ1_ENABLED(p->ctl_b)) || (p->irq_b2 && IRQ2_ENABLED(p->ctl_b))) new_state = 1;
  177.     if (new_state != p->irq_b_state)
  178.     {
  179.         p->irq_b_state = new_state;
  180.         if (p->intf->irq_b_func) update_shared_irq_handler(p->intf->irq_b_func);
  181.     }
  182. }
  183.  
  184.  
  185. /******************* CPU interface for PIA read *******************/
  186.  
  187. int pia_read(int which, int offset)
  188. {
  189.     struct pia6821 *p = pia + which;
  190.     int val = 0;
  191.  
  192.     /* adjust offset for 16-bit and ordering */
  193.     if (p->addr & PIA_16BIT) offset /= 2;
  194.     offset &= 3;
  195.     if (p->addr & PIA_ALTERNATE_ORDERING) offset = swizzle_address[offset];
  196.  
  197.     switch (offset)
  198.     {
  199.         /******************* port A output/DDR read *******************/
  200.         case PIA_DDRA:
  201.  
  202.             /* read output register */
  203.             if (OUTPUT_SELECTED(p->ctl_a))
  204.             {
  205.                 /* update the input */
  206.                 if (p->intf->in_a_func) p->in_a = p->intf->in_a_func(0);
  207.  
  208.                 /* combine input and output values */
  209.                 val = (p->out_a & p->ddr_a) + (p->in_a & ~p->ddr_a);
  210.  
  211.                 /* IRQ flags implicitly cleared by a read */
  212.                 p->irq_a1 = p->irq_a2 = 0;
  213.                 update_6821_interrupts(p);
  214.  
  215.                 /* CA2 is configured as output and in read strobe mode */
  216.                 if (C2_OUTPUT(p->ctl_a) && C2_STROBE_MODE(p->ctl_a))
  217.                 {
  218.                     /* this will cause a transition low; call the output function if we're currently high */
  219.                     if (p->out_ca2)
  220.                         if (p->intf->out_ca2_func) p->intf->out_ca2_func(0, 0);
  221.                     p->out_ca2 = 0;
  222.  
  223.                     /* if the CA2 strobe is cleared by the E, reset it right away */
  224.                     if (STROBE_E_RESET(p->ctl_a))
  225.                     {
  226.                         if (p->intf->out_ca2_func) p->intf->out_ca2_func(0, 1);
  227.                         p->out_ca2 = 1;
  228.                     }
  229.                 }
  230.  
  231.                 LOG(("PIA%d read port A = %02X\n", which, val));
  232.             }
  233.  
  234.             /* read DDR register */
  235.             else
  236.             {
  237.                 val = p->ddr_a;
  238.                 LOG(("PIA%d read DDR A = %02X\n", which, val));
  239.             }
  240.             break;
  241.  
  242.         /******************* port B output/DDR read *******************/
  243.         case PIA_DDRB:
  244.  
  245.             /* read output register */
  246.             if (OUTPUT_SELECTED(p->ctl_b))
  247.             {
  248.                 /* update the input */
  249.                 if (p->intf->in_b_func) p->in_b = p->intf->in_b_func(0);
  250.  
  251.                 /* combine input and output values */
  252.                 val = (p->out_b & p->ddr_b) + (p->in_b & ~p->ddr_b);
  253.  
  254.                 /* IRQ flags implicitly cleared by a read */
  255.                 p->irq_b1 = p->irq_b2 = 0;
  256.                 update_6821_interrupts(p);
  257.  
  258.                 LOG(("PIA%d read port B = %02X\n", which, val));
  259.             }
  260.  
  261.             /* read DDR register */
  262.             else
  263.             {
  264.                 val = p->ddr_b;
  265.                 LOG(("PIA%d read DDR B = %02X\n", which, val));
  266.             }
  267.             break;
  268.  
  269.         /******************* port A control read *******************/
  270.         case PIA_CTLA:
  271.  
  272.             /* Update CA1 & CA2 if callback exists, these in turn may update IRQ's */
  273.             if (p->intf->in_ca1_func) pia_set_input_ca1(which, p->intf->in_ca1_func(0));
  274.             if (p->intf->in_ca2_func) pia_set_input_ca2(which, p->intf->in_ca2_func(0));
  275.  
  276.             /* read control register */
  277.             val = p->ctl_a;
  278.  
  279.             /* set the IRQ flags if we have pending IRQs */
  280.             if (p->irq_a1) val |= PIA_IRQ1;
  281.             if (p->irq_a2 && C2_INPUT(p->ctl_a)) val |= PIA_IRQ2;
  282.  
  283.             LOG(("PIA%d read control A = %02X\n", which, val));
  284.             break;
  285.  
  286.         /******************* port B control read *******************/
  287.         case PIA_CTLB:
  288.  
  289.             /* Update CB1 & CB2 if callback exists, these in turn may update IRQ's */
  290.             if (p->intf->in_cb1_func) pia_set_input_cb1(which, p->intf->in_cb1_func(0));
  291.             if (p->intf->in_cb2_func) pia_set_input_cb2(which, p->intf->in_cb2_func(0));
  292.  
  293.             /* read control register */
  294.             val = p->ctl_b;
  295.  
  296.             /* set the IRQ flags if we have pending IRQs */
  297.             if (p->irq_b1) val |= PIA_IRQ1;
  298.             if (p->irq_b2 && C2_INPUT(p->ctl_b)) val |= PIA_IRQ2;
  299.  
  300.             LOG(("PIA%d read control B = %02X\n", which, val));
  301.             break;
  302.     }
  303.  
  304.     /* adjust final output value for 16-bit */
  305.     if (p->addr & PIA_16BIT)
  306.     {
  307.         if (p->addr & PIA_AUTOSENSE)
  308.             val = (val << 8) | val;
  309.         else if (p->addr & PIA_UPPER)
  310.             val <<= 8;
  311.     }
  312.  
  313.     return val;
  314. }
  315.  
  316.  
  317. /******************* CPU interface for PIA write *******************/
  318.  
  319. void pia_write(int which, int offset, int data)
  320. {
  321.     struct pia6821 *p = pia + which;
  322.  
  323.     /* adjust offset for 16-bit and ordering */
  324.     if (p->addr & PIA_16BIT) offset /= 2;
  325.     offset &= 3;
  326.     if (p->addr & PIA_ALTERNATE_ORDERING) offset = swizzle_address[offset];
  327.  
  328.     /* adjust data for 16-bit */
  329.     if (p->addr & PIA_16BIT)
  330.     {
  331.         if (p->addr & PIA_AUTOSENSE)
  332.         {
  333.             if (!(data & 0x00ff0000))
  334.                 data &= 0xff;
  335.             else
  336.                 data = (data >> 8) & 0xff;
  337.         }
  338.         else if (p->addr & PIA_UPPER)
  339.         {
  340.             if (data & 0xff000000)
  341.                 return;
  342.             data = (data >> 8) & 0xff;
  343.         }
  344.         else
  345.         {
  346.             if (data & 0x00ff0000)
  347.                 return;
  348.             data &= 0xff;
  349.         }
  350.     }
  351.  
  352.     switch (offset)
  353.     {
  354.         /******************* port A output/DDR write *******************/
  355.         case PIA_DDRA:
  356.  
  357.             /* write output register */
  358.             if (OUTPUT_SELECTED(p->ctl_a))
  359.             {
  360.                 LOG(("PIA%d port A write = %02X\n", which, data));
  361.  
  362.                 /* update the output value */
  363.                 p->out_a = data;/* & p->ddr_a; */    /* NS990130 - don't mask now, DDR could change later */
  364.  
  365.                 /* send it to the output function */
  366.                 if (p->intf->out_a_func && p->ddr_a) p->intf->out_a_func(0, p->out_a & p->ddr_a);    /* NS990130 */
  367.             }
  368.  
  369.             /* write DDR register */
  370.             else
  371.             {
  372.                 LOG(("PIA%d DDR A write = %02X\n", which, data));
  373.  
  374.                 if (p->ddr_a != data)
  375.                 {
  376.                     /* NS990130 - if DDR changed, call the callback again */
  377.                     p->ddr_a = data;
  378.  
  379.                     /* send it to the output function */
  380.                     if (p->intf->out_a_func && p->ddr_a) p->intf->out_a_func(0, p->out_a & p->ddr_a);
  381.                 }
  382.             }
  383.             break;
  384.  
  385.         /******************* port B output/DDR write *******************/
  386.         case PIA_DDRB:
  387.  
  388.             /* write output register */
  389.             if (OUTPUT_SELECTED(p->ctl_b))
  390.             {
  391.                 LOG(("PIA%d port B write = %02X\n", which, data));
  392.  
  393.                 /* update the output value */
  394.                 p->out_b = data;/* & p->ddr_b */    /* NS990130 - don't mask now, DDR could change later */
  395.  
  396.                 /* send it to the output function */
  397.                 if (p->intf->out_b_func && p->ddr_b) p->intf->out_b_func(0, p->out_b & p->ddr_b);    /* NS990130 */
  398.  
  399.                 /* CB2 is configured as output and in write strobe mode */
  400.                 if (C2_OUTPUT(p->ctl_b) && C2_STROBE_MODE(p->ctl_b))
  401.                 {
  402.                     /* this will cause a transition low; call the output function if we're currently high */
  403.                     if (p->out_cb2)
  404.                         if (p->intf->out_cb2_func) p->intf->out_cb2_func(0, 0);
  405.                     p->out_cb2 = 0;
  406.  
  407.                     /* if the CB2 strobe is cleared by the E, reset it right away */
  408.                     if (STROBE_E_RESET(p->ctl_b))
  409.                     {
  410.                         if (p->intf->out_cb2_func) p->intf->out_cb2_func(0, 1);
  411.                         p->out_cb2 = 1;
  412.                     }
  413.                 }
  414.             }
  415.  
  416.             /* write DDR register */
  417.             else
  418.             {
  419.                 LOG(("PIA%d DDR B write = %02X\n", which, data));
  420.  
  421.                 if (p->ddr_b != data)
  422.                 {
  423.                     /* NS990130 - if DDR changed, call the callback again */
  424.                     p->ddr_b = data;
  425.  
  426.                     /* send it to the output function */
  427.                     if (p->intf->out_b_func && p->ddr_b) p->intf->out_b_func(0, p->out_b & p->ddr_b);
  428.                 }
  429.             }
  430.             break;
  431.  
  432.         /******************* port A control write *******************/
  433.         case PIA_CTLA:
  434.  
  435.             /* Bit 7 and 6 read only - PD 16/01/00 */
  436.  
  437.             data &= 0x3f;
  438.  
  439.  
  440.             LOG(("PIA%d control A write = %02X\n", which, data));
  441.  
  442.             /* CA2 is configured as output and in set/reset mode */
  443.             /* 10/22/98 - MAB/FMP - any C2_OUTPUT should affect CA2 */
  444. //            if (C2_OUTPUT(data) && C2_SET_MODE(data))
  445.             if (C2_OUTPUT(data))
  446.             {
  447.                 /* determine the new value */
  448.                 int temp = SET_C2(data) ? 1 : 0;
  449.  
  450.                 /* if this creates a transition, call the CA2 output function */
  451.                 if (p->out_ca2 ^ temp)
  452.                     if (p->intf->out_ca2_func) p->intf->out_ca2_func(0, temp);
  453.  
  454.                 /* set the new value */
  455.                 p->out_ca2 = temp;
  456.             }
  457.  
  458.             /* update the control register */
  459.             p->ctl_a = data;
  460.  
  461.             /* update externals */
  462.             update_6821_interrupts(p);
  463.             break;
  464.  
  465.         /******************* port B control write *******************/
  466.         case PIA_CTLB:
  467.  
  468.             /* Bit 7 and 6 read only - PD 16/01/00 */
  469.  
  470.             data &= 0x3f;
  471.  
  472.             LOG(("PIA%d control B write = %02X\n", which, data));
  473.  
  474.             /* CB2 is configured as output and in set/reset mode */
  475.             /* 10/22/98 - MAB/FMP - any C2_OUTPUT should affect CB2 */
  476. //            if (C2_OUTPUT(data) && C2_SET_MODE(data))
  477.             if (C2_OUTPUT(data))
  478.             {
  479.                 /* determine the new value */
  480.                 int temp = SET_C2(data) ? 1 : 0;
  481.  
  482.                 /* if this creates a transition, call the CA2 output function */
  483.                 if (p->out_cb2 ^ temp)
  484.                     if (p->intf->out_cb2_func) p->intf->out_cb2_func(0, temp);
  485.  
  486.                 /* set the new value */
  487.                 p->out_cb2 = temp;
  488.             }
  489.  
  490.             /* update the control register */
  491.             p->ctl_b = data;
  492.  
  493.             /* update externals */
  494.             update_6821_interrupts(p);
  495.             break;
  496.     }
  497. }
  498.  
  499.  
  500. /******************* interface setting PIA port A input *******************/
  501.  
  502. void pia_set_input_a(int which, int data)
  503. {
  504.     struct pia6821 *p = pia + which;
  505.  
  506.     /* set the input, what could be easier? */
  507.     p->in_a = data;
  508. }
  509.  
  510.  
  511.  
  512. /******************* interface setting PIA port CA1 input *******************/
  513.  
  514. void pia_set_input_ca1(int which, int data)
  515. {
  516.     struct pia6821 *p = pia + which;
  517.  
  518.     /* limit the data to 0 or 1 */
  519.     data = data ? 1 : 0;
  520.  
  521.     /* the new state has caused a transition */
  522.     if (p->in_ca1 ^ data)
  523.     {
  524.         /* handle the active transition */
  525.         if ((data && C1_LOW_TO_HIGH(p->ctl_a)) || (!data && C1_HIGH_TO_LOW(p->ctl_a)))
  526.         {
  527.             /* mark the IRQ */
  528.             p->irq_a1 = 1;
  529.  
  530.             /* update externals */
  531.             update_6821_interrupts(p);
  532.  
  533.             /* CA2 is configured as output and in read strobe mode and cleared by a CA1 transition */
  534.             if (C2_OUTPUT(p->ctl_a) && C2_STROBE_MODE(p->ctl_a) && STROBE_C1_RESET(p->ctl_a))
  535.             {
  536.                 /* call the CA2 output function */
  537.                 if (!p->out_ca2)
  538.                     if (p->intf->out_ca2_func) p->intf->out_ca2_func(0, 1);
  539.  
  540.                 /* clear CA2 */
  541.                 p->out_ca2 = 1;
  542.             }
  543.         }
  544.     }
  545.  
  546.     /* set the new value for CA1 */
  547.     p->in_ca1 = data;
  548. }
  549.  
  550.  
  551.  
  552. /******************* interface setting PIA port CA2 input *******************/
  553.  
  554. void pia_set_input_ca2(int which, int data)
  555. {
  556.     struct pia6821 *p = pia + which;
  557.  
  558.     /* limit the data to 0 or 1 */
  559.     data = data ? 1 : 0;
  560.  
  561.     /* CA2 is in input mode */
  562.     if (C2_INPUT(p->ctl_a))
  563.     {
  564.         /* the new state has caused a transition */
  565.         if (p->in_ca2 ^ data)
  566.         {
  567.             /* handle the active transition */
  568.             if ((data && C2_LOW_TO_HIGH(p->ctl_a)) || (!data && C2_HIGH_TO_LOW(p->ctl_a)))
  569.             {
  570.                 /* mark the IRQ */
  571.                 p->irq_a2 = 1;
  572.  
  573.                 /* update externals */
  574.                 update_6821_interrupts(p);
  575.             }
  576.         }
  577.     }
  578.  
  579.     /* set the new value for CA2 */
  580.     p->in_ca2 = data;
  581. }
  582.  
  583.  
  584.  
  585. /******************* interface setting PIA port B input *******************/
  586.  
  587. void pia_set_input_b(int which, int data)
  588. {
  589.     struct pia6821 *p = pia + which;
  590.  
  591.     /* set the input, what could be easier? */
  592.     p->in_b = data;
  593. }
  594.  
  595.  
  596.  
  597. /******************* interface setting PIA port CB1 input *******************/
  598.  
  599. void pia_set_input_cb1(int which, int data)
  600. {
  601.     struct pia6821 *p = pia + which;
  602.  
  603.     /* limit the data to 0 or 1 */
  604.     data = data ? 1 : 0;
  605.  
  606.     /* the new state has caused a transition */
  607.     if (p->in_cb1 ^ data)
  608.     {
  609.         /* handle the active transition */
  610.         if ((data && C1_LOW_TO_HIGH(p->ctl_b)) || (!data && C1_HIGH_TO_LOW(p->ctl_b)))
  611.         {
  612.             /* mark the IRQ */
  613.             p->irq_b1 = 1;
  614.  
  615.             /* update externals */
  616.             update_6821_interrupts(p);
  617.  
  618.             /* CB2 is configured as output and in write strobe mode and cleared by a CA1 transition */
  619.             if (C2_OUTPUT(p->ctl_b) && C2_STROBE_MODE(p->ctl_b) && STROBE_C1_RESET(p->ctl_b))
  620.             {
  621.                 /* the IRQ1 flag must have also been cleared */
  622.                 if (!p->irq_b1)
  623.                 {
  624.                     /* call the CB2 output function */
  625.                     if (!p->out_cb2)
  626.                         if (p->intf->out_cb2_func) p->intf->out_cb2_func(0, 1);
  627.  
  628.                     /* clear CB2 */
  629.                     p->out_cb2 = 1;
  630.                 }
  631.             }
  632.         }
  633.     }
  634.  
  635.     /* set the new value for CB1 */
  636.     p->in_cb1 = data;
  637. }
  638.  
  639.  
  640.  
  641. /******************* interface setting PIA port CB2 input *******************/
  642.  
  643. void pia_set_input_cb2(int which, int data)
  644. {
  645.     struct pia6821 *p = pia + which;
  646.  
  647.     /* limit the data to 0 or 1 */
  648.     data = data ? 1 : 0;
  649.  
  650.     /* CB2 is in input mode */
  651.     if (C2_INPUT(p->ctl_b))
  652.     {
  653.         /* the new state has caused a transition */
  654.         if (p->in_cb2 ^ data)
  655.         {
  656.             /* handle the active transition */
  657.             if ((data && C2_LOW_TO_HIGH(p->ctl_b)) || (!data && C2_HIGH_TO_LOW(p->ctl_b)))
  658.             {
  659.                 /* mark the IRQ */
  660.                 p->irq_b2 = 1;
  661.  
  662.                 /* update externals */
  663.                 update_6821_interrupts(p);
  664.             }
  665.         }
  666.     }
  667.  
  668.     /* set the new value for CA2 */
  669.     p->in_cb2 = data;
  670. }
  671.  
  672.  
  673.  
  674. /******************* Standard 8-bit CPU interfaces, D0-D7 *******************/
  675.  
  676. READ_HANDLER( pia_0_r ) { return pia_read(0, offset); }
  677. READ_HANDLER( pia_1_r ) { return pia_read(1, offset); }
  678. READ_HANDLER( pia_2_r ) { return pia_read(2, offset); }
  679. READ_HANDLER( pia_3_r ) { return pia_read(3, offset); }
  680. READ_HANDLER( pia_4_r ) { return pia_read(4, offset); }
  681. READ_HANDLER( pia_5_r ) { return pia_read(5, offset); }
  682. READ_HANDLER( pia_6_r ) { return pia_read(6, offset); }
  683. READ_HANDLER( pia_7_r ) { return pia_read(7, offset); }
  684.  
  685. WRITE_HANDLER( pia_0_w ) { pia_write(0, offset, data); }
  686. WRITE_HANDLER( pia_1_w ) { pia_write(1, offset, data); }
  687. WRITE_HANDLER( pia_2_w ) { pia_write(2, offset, data); }
  688. WRITE_HANDLER( pia_3_w ) { pia_write(3, offset, data); }
  689. WRITE_HANDLER( pia_4_w ) { pia_write(4, offset, data); }
  690. WRITE_HANDLER( pia_5_w ) { pia_write(5, offset, data); }
  691. WRITE_HANDLER( pia_6_w ) { pia_write(6, offset, data); }
  692. WRITE_HANDLER( pia_7_w ) { pia_write(7, offset, data); }
  693.  
  694. /******************* 8-bit A/B port interfaces *******************/
  695.  
  696. WRITE_HANDLER( pia_0_porta_w ) { pia_set_input_a(0, data); }
  697. WRITE_HANDLER( pia_1_porta_w ) { pia_set_input_a(1, data); }
  698. WRITE_HANDLER( pia_2_porta_w ) { pia_set_input_a(2, data); }
  699. WRITE_HANDLER( pia_3_porta_w ) { pia_set_input_a(3, data); }
  700. WRITE_HANDLER( pia_4_porta_w ) { pia_set_input_a(4, data); }
  701. WRITE_HANDLER( pia_5_porta_w ) { pia_set_input_a(5, data); }
  702. WRITE_HANDLER( pia_6_porta_w ) { pia_set_input_a(6, data); }
  703. WRITE_HANDLER( pia_7_porta_w ) { pia_set_input_a(7, data); }
  704.  
  705. WRITE_HANDLER( pia_0_portb_w ) { pia_set_input_b(0, data); }
  706. WRITE_HANDLER( pia_1_portb_w ) { pia_set_input_b(1, data); }
  707. WRITE_HANDLER( pia_2_portb_w ) { pia_set_input_b(2, data); }
  708. WRITE_HANDLER( pia_3_portb_w ) { pia_set_input_b(3, data); }
  709. WRITE_HANDLER( pia_4_portb_w ) { pia_set_input_b(4, data); }
  710. WRITE_HANDLER( pia_5_portb_w ) { pia_set_input_b(5, data); }
  711. WRITE_HANDLER( pia_6_portb_w ) { pia_set_input_b(6, data); }
  712. WRITE_HANDLER( pia_7_portb_w ) { pia_set_input_b(7, data); }
  713.  
  714. READ_HANDLER( pia_0_porta_r ) { return pia[0].in_a; }
  715. READ_HANDLER( pia_1_porta_r ) { return pia[1].in_a; }
  716. READ_HANDLER( pia_2_porta_r ) { return pia[2].in_a; }
  717. READ_HANDLER( pia_3_porta_r ) { return pia[3].in_a; }
  718. READ_HANDLER( pia_4_porta_r ) { return pia[4].in_a; }
  719. READ_HANDLER( pia_5_porta_r ) { return pia[5].in_a; }
  720. READ_HANDLER( pia_6_porta_r ) { return pia[6].in_a; }
  721. READ_HANDLER( pia_7_porta_r ) { return pia[7].in_a; }
  722.  
  723. READ_HANDLER( pia_0_portb_r ) { return pia[0].in_b; }
  724. READ_HANDLER( pia_1_portb_r ) { return pia[1].in_b; }
  725. READ_HANDLER( pia_2_portb_r ) { return pia[2].in_b; }
  726. READ_HANDLER( pia_3_portb_r ) { return pia[3].in_b; }
  727. READ_HANDLER( pia_4_portb_r ) { return pia[4].in_b; }
  728. READ_HANDLER( pia_5_portb_r ) { return pia[5].in_b; }
  729. READ_HANDLER( pia_6_portb_r ) { return pia[6].in_b; }
  730. READ_HANDLER( pia_7_portb_r ) { return pia[7].in_b; }
  731.  
  732. /******************* 1-bit CA1/CA2/CB1/CB2 port interfaces *******************/
  733.  
  734. WRITE_HANDLER( pia_0_ca1_w ) { pia_set_input_ca1(0, data); }
  735. WRITE_HANDLER( pia_1_ca1_w ) { pia_set_input_ca1(1, data); }
  736. WRITE_HANDLER( pia_2_ca1_w ) { pia_set_input_ca1(2, data); }
  737. WRITE_HANDLER( pia_3_ca1_w ) { pia_set_input_ca1(3, data); }
  738. WRITE_HANDLER( pia_4_ca1_w ) { pia_set_input_ca1(4, data); }
  739. WRITE_HANDLER( pia_5_ca1_w ) { pia_set_input_ca1(5, data); }
  740. WRITE_HANDLER( pia_6_ca1_w ) { pia_set_input_ca1(6, data); }
  741. WRITE_HANDLER( pia_7_ca1_w ) { pia_set_input_ca1(7, data); }
  742. WRITE_HANDLER( pia_0_ca2_w ) { pia_set_input_ca2(0, data); }
  743. WRITE_HANDLER( pia_1_ca2_w ) { pia_set_input_ca2(1, data); }
  744. WRITE_HANDLER( pia_2_ca2_w ) { pia_set_input_ca2(2, data); }
  745. WRITE_HANDLER( pia_3_ca2_w ) { pia_set_input_ca2(3, data); }
  746. WRITE_HANDLER( pia_4_ca2_w ) { pia_set_input_ca2(4, data); }
  747. WRITE_HANDLER( pia_5_ca2_w ) { pia_set_input_ca2(5, data); }
  748. WRITE_HANDLER( pia_6_ca2_w ) { pia_set_input_ca2(6, data); }
  749. WRITE_HANDLER( pia_7_ca2_w ) { pia_set_input_ca2(7, data); }
  750.  
  751. WRITE_HANDLER( pia_0_cb1_w ) { pia_set_input_cb1(0, data); }
  752. WRITE_HANDLER( pia_1_cb1_w ) { pia_set_input_cb1(1, data); }
  753. WRITE_HANDLER( pia_2_cb1_w ) { pia_set_input_cb1(2, data); }
  754. WRITE_HANDLER( pia_3_cb1_w ) { pia_set_input_cb1(3, data); }
  755. WRITE_HANDLER( pia_4_cb1_w ) { pia_set_input_cb1(4, data); }
  756. WRITE_HANDLER( pia_5_cb1_w ) { pia_set_input_cb1(5, data); }
  757. WRITE_HANDLER( pia_6_cb1_w ) { pia_set_input_cb1(6, data); }
  758. WRITE_HANDLER( pia_7_cb1_w ) { pia_set_input_cb1(7, data); }
  759. WRITE_HANDLER( pia_0_cb2_w ) { pia_set_input_cb2(0, data); }
  760. WRITE_HANDLER( pia_1_cb2_w ) { pia_set_input_cb2(1, data); }
  761. WRITE_HANDLER( pia_2_cb2_w ) { pia_set_input_cb2(2, data); }
  762. WRITE_HANDLER( pia_3_cb2_w ) { pia_set_input_cb2(3, data); }
  763. WRITE_HANDLER( pia_4_cb2_w ) { pia_set_input_cb2(4, data); }
  764. WRITE_HANDLER( pia_5_cb2_w ) { pia_set_input_cb2(5, data); }
  765. WRITE_HANDLER( pia_6_cb2_w ) { pia_set_input_cb2(6, data); }
  766. WRITE_HANDLER( pia_7_cb2_w ) { pia_set_input_cb2(7, data); }
  767.  
  768. READ_HANDLER( pia_0_ca1_r ) { return pia[0].in_ca1; }
  769. READ_HANDLER( pia_1_ca1_r ) { return pia[1].in_ca1; }
  770. READ_HANDLER( pia_2_ca1_r ) { return pia[2].in_ca1; }
  771. READ_HANDLER( pia_3_ca1_r ) { return pia[3].in_ca1; }
  772. READ_HANDLER( pia_4_ca1_r ) { return pia[4].in_ca1; }
  773. READ_HANDLER( pia_5_ca1_r ) { return pia[5].in_ca1; }
  774. READ_HANDLER( pia_6_ca1_r ) { return pia[6].in_ca1; }
  775. READ_HANDLER( pia_7_ca1_r ) { return pia[7].in_ca1; }
  776. READ_HANDLER( pia_0_ca2_r ) { return pia[0].in_ca2; }
  777. READ_HANDLER( pia_1_ca2_r ) { return pia[1].in_ca2; }
  778. READ_HANDLER( pia_2_ca2_r ) { return pia[2].in_ca2; }
  779. READ_HANDLER( pia_3_ca2_r ) { return pia[3].in_ca2; }
  780. READ_HANDLER( pia_4_ca2_r ) { return pia[4].in_ca2; }
  781. READ_HANDLER( pia_5_ca2_r ) { return pia[5].in_ca2; }
  782. READ_HANDLER( pia_6_ca2_r ) { return pia[6].in_ca2; }
  783. READ_HANDLER( pia_7_ca2_r ) { return pia[7].in_ca2; }
  784.  
  785. READ_HANDLER( pia_0_cb1_r ) { return pia[0].in_cb1; }
  786. READ_HANDLER( pia_1_cb1_r ) { return pia[1].in_cb1; }
  787. READ_HANDLER( pia_2_cb1_r ) { return pia[2].in_cb1; }
  788. READ_HANDLER( pia_3_cb1_r ) { return pia[3].in_cb1; }
  789. READ_HANDLER( pia_4_cb1_r ) { return pia[4].in_cb1; }
  790. READ_HANDLER( pia_5_cb1_r ) { return pia[5].in_cb1; }
  791. READ_HANDLER( pia_6_cb1_r ) { return pia[6].in_cb1; }
  792. READ_HANDLER( pia_7_cb1_r ) { return pia[7].in_cb1; }
  793. READ_HANDLER( pia_0_cb2_r ) { return pia[0].in_cb2; }
  794. READ_HANDLER( pia_1_cb2_r ) { return pia[1].in_cb2; }
  795. READ_HANDLER( pia_2_cb2_r ) { return pia[2].in_cb2; }
  796. READ_HANDLER( pia_3_cb2_r ) { return pia[3].in_cb2; }
  797. READ_HANDLER( pia_4_cb2_r ) { return pia[4].in_cb2; }
  798. READ_HANDLER( pia_5_cb2_r ) { return pia[5].in_cb2; }
  799. READ_HANDLER( pia_6_cb2_r ) { return pia[6].in_cb2; }
  800. READ_HANDLER( pia_7_cb2_r ) { return pia[7].in_cb2; }
  801.